mod utils;

slint::include_modules!();

use windows_sys::{
    Win32::Foundation::*, Win32::System::SystemServices::*, Win32::System::Threading::*,
    Win32::UI::WindowsAndMessaging::*, core::*,
};

use core::ptr;
use std::ffi::c_void;

#[unsafe(no_mangle)]
#[allow(non_snake_case, unused_variables)]
extern "system" fn DllMain(dll_module: HINSTANCE, call_reason: u32, _: *mut ()) -> bool {
    match call_reason {
        DLL_PROCESS_ATTACH => attach(),
        DLL_PROCESS_DETACH => detach(),
        _ => (),
    }

    true
}

fn attach() {
    std::thread::spawn(|| {
        if let Err(e) = run_slint_ui() {
            eprintln!("Slint UI error: {}", e);
        }
    });
}

fn detach() {
    // DLL_PROCESS_DETACH 的逻辑
    // 在这里通常不需要做什么，因为进程退出会自动清理。
}

fn run_slint_ui() -> Result<(), slint::PlatformError> {
    let ui = MainWindow::new()?;

    unsafe {
        let pid = GetCurrentProcessId();
        // TODO: 1. 这里需要加上循环, 因为有可能注入时, 主窗口还没创建
        // TODO: 2. 写一个获取顶层窗口的 find_window, 当前进程中根据窗口类名过滤
        let window = utils::win32::find_window_by_pid(pid).expect("没有找到窗口");
        if PREV_WNDPROC == None {
            let result = SetWindowLongPtrW(window, GWLP_WNDPROC, new_wndproc as isize);
            PREV_WNDPROC = Some(std::mem::transmute(result));
        }
    }

    ui.on_show_message({
        let ui_weak = ui.as_weak();
        move |message| {
            println!("Message: {}", message);
            let ui = ui_weak.unwrap();
            ui.set_count(ui.get_count() + 10);
        }
    });

    ui.run()
}

static mut PREV_WNDPROC: WNDPROC = None;

fn new_wndproc(window: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
    unsafe {
        match msg {
            WM_KEYUP => {
                MessageBoxW(window, w!("按键"), w!("提示"), MB_OK | MB_ICONINFORMATION);
                return 0;
            }
            _ => (),
        }
        CallWindowProcW(PREV_WNDPROC, window, msg, wparam, lparam)
    }
}
